package org.feit.findword;

import org.feit.findword.Synchronizer.Finalizer;
import org.feit.findword.game.Game;
import org.feit.findword.game.Game.GameStatus;
import org.feit.findword.view.GameBoardView;
import org.feit.findword.view.StatsView;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PlayGame extends Activity implements Finalizer {
	private static final String TAG = "PlayGame";

	private Synchronizer mSynch;
	private Game mGame;
	private Menu mMenu;
	private String mAppTitle;
	private GameBoardView mGameView;
	private TextView mLoading;
	private ProgressBar mLoadingProgress;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mAppTitle = getString(R.string.app_name);
		setContentView(R.layout.loading_view);
		mLoading = (TextView) findViewById(R.id.loading);
		mLoadingProgress = (ProgressBar) findViewById(R.id.pbLoading);
		mGameView = (GameBoardView) findViewById(R.id.game_view);
		Log.d(TAG, "onCreate");
		if (savedInstanceState != null) {
			Log.d(TAG, "restoring instance state");
			try {
				restoreGame(savedInstanceState);
			} catch (Exception e) {
				Log.e(TAG, "error restoring state", e);
			}
			return;
		}
		String action = getIntent().getAction();
		if (action.equals("org.feit.findword.action.RESTORE_GAME")) {
			Log.d(TAG, "restoring game");
			restoreGame();
		} else if (action.equals("org.feit.findword.action.NEW_GAME")) {
			Log.d(TAG, "starting new game");
			newGame();
		} else {
			Log.d(TAG, "Whoa there, friend!");
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu m) {
		// Log.d(TAG,"onCreateOptionsMenu");

		mMenu = m;

		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.game_menu, mMenu);

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Log.d(TAG,"onOptionsItemSelected");

		switch (item.getItemId()) {
		case R.id.rotate:
			mGame.rotateBoard();
			break;
		case R.id.save_game:
			mSynch.abort();
			saveGame();
			finish();
			break;
		case R.id.end_game:
			mGame.endNow();
		}
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		return mGame.getStatus() == Game.GameStatus.GAME_RUNNING;
	}

	private void newGame() {
		setContentView(R.layout.loading_view);
		setTitle(getString(R.string.loading_dictionary));
		Thread gameThread = new Thread(mNewGameRunnable);
		gameThread.start();

	}

	final Runnable mNewGameRunnable = new Runnable() {

		@Override
		public void run() {
			mGame = new Game(PlayGame.this);
			Log.d(TAG, "created game");
			mGameLoadedHandler.sendEmptyMessage(0);
		}
	};
	final Handler mGameLoadedHandler = new Handler() {
		public void handleMessage(Message msg) {
			restoreGame(mGame);
			setGameState();
		};
	};

	private void setGameState() {
		switch (mGame.getStatus()) {
		case GAME_STARTING:
			Log.d(TAG, "onResume: GAME_STARTING");
			mGame.start();
			mSynch.start();
			break;
		case GAME_PAUSED:
			Log.d(TAG, "onResume: GAME_PAUSED");
			mGame.unpause();
			mSynch.start();
			break;
		case GAME_NEW_LEVEL:
			Log.d(TAG, "onResume: GAME_NEW_LEVEL");
			nextLevel();
			break;
		case GAME_FINISHED:
			Log.d(TAG, "onResume: GAME_FINISHED");
			score();
			break;
		}
	}

	private void restoreGame() {
		SharedPreferences prefs = getSharedPreferences("prefs_game_file",
				Context.MODE_PRIVATE);
		clearSavedGame();
		mGame = new Game(this, prefs);
		restoreGame(mGame);
	}

	private void restoreGame(Bundle bun) {
		mGame = new Game(this, bun);
		restoreGame(mGame);
	}

	private void restoreGame(Game game) {

		Log.d(TAG, "restored game");
		setTitle(String.format("%s - %s %d (%d%%)", mAppTitle,
				getString(R.string.level), game.getCurrentLevel(), game
						.getLevelPercent()));
		setContentView(R.layout.game_view);
		mGameView = (GameBoardView) findViewById(R.id.game_view);
		mGameView.setGame(game);

		if (mSynch != null) {
			mSynch.abort();
		}
		mSynch = new Synchronizer();
		mSynch.setCounter(game);
		mSynch.addEvent(mGameView);
		mSynch.setFinalizer(PlayGame.this);

		// Log.d(TAG,"restoreGame ends");
	}

	private void saveGame() {
		if (mGame.getStatus() == Game.GameStatus.GAME_RUNNING) {
			// Log.d(TAG,"Saving");
			SharedPreferences prefs = getSharedPreferences("prefs_game_file",
					Context.MODE_PRIVATE);
			mGame.pause();
			mGame.save(prefs.edit());
		}
	}

	private void saveGame(Bundle state) {
		if (mGame.getStatus() == Game.GameStatus.GAME_RUNNING) {
			// Log.d(TAG,"Saving");
			mGame.pause();
			mGame.save(state);
		}
	}

	public void onPause() {
		super.onPause();
		Log.d(TAG, "Pausing");
		mSynch.abort();
		saveGame();
	}

	public void onResume() {
		super.onResume();
		Log.d(TAG, "onResume:" + mGame + "," + mSynch);
		if (mGame == null) {
			return;
		}

		switch (mGame.getStatus()) {
		case GAME_STARTING:
			Log.d(TAG, "onResume: GAME_STARTING");
			mGame.start();
			mSynch.start();
			break;
		case GAME_PAUSED:
			Log.d(TAG, "onResume: GAME_PAUSED");
			mGame.unpause();
			mSynch.start();
			break;
		case GAME_NEW_LEVEL:
			Log.d(TAG, "onResume: GAME_NEW_LEVEL");
			nextLevel();
			break;
		case GAME_FINISHED:
			Log.d(TAG, "onResume: GAME_FINISHED");
			score();
			break;
		}
		Log.d(TAG, "onResume finished");
	}

	public void doFinalEvent() {
		if (mGame.getStatus() == GameStatus.GAME_FINISHED) {
			score();
		}
		if (mGame.getStatus() == GameStatus.GAME_NEW_LEVEL) {
			nextLevel();
		}
	}

	private void clearSavedGame() {
		SharedPreferences prefs = getSharedPreferences("prefs_game_file",
				Context.MODE_PRIVATE);

		SharedPreferences.Editor editor = prefs.edit();
		editor.putBoolean("activeGame", false);
		editor.commit();

	}

	private void score() {
		// Log.d(TAG,"Finishing");

		mSynch.abort();
		clearSavedGame();

		Bundle bun = new Bundle();
		mGame.save(bun);

		Intent scoreIntent = new Intent(this, HighScores.class);
		scoreIntent.putExtras(bun);

		startActivity(scoreIntent);

		finish();
	}

	private void nextLevel() {
		mSynch.abort();
		clearSavedGame();

		setContentView(R.layout.level_view);
		StatsView statsView = (StatsView) findViewById(R.id.stats_view);
		statsView.setGame(mGame);
	}

	public void onBtnClick(View v) {
		setContentView(R.layout.loading_view);
		setTitle(getString(R.string.loading_dictionary));
		Log.d(TAG, "next level");
		Thread nextLevelThread = new Thread(mNextLevelRunnable);
		nextLevelThread.start();

	}

	final Runnable mNextLevelRunnable = new Runnable() {

		@Override
		public void run() {
			mGame.nextLevel();
			Log.d(TAG, "next level loaded");
			mGameLoadedHandler.sendEmptyMessage(0);
		}
	};

	public void onStop() {
		super.onStop();
		// Log.d(TAG,"onStop()");
	}

	public void onDestroy() {
		super.onDestroy();
		// Log.d(TAG,"onDestroy()"+isFinishing());
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		Log.d(TAG, "onSaveInstanceState");
		saveGame(outState);
	}

}
